package io.kiki.sba.registry.server.metadata.resource;

import io.kiki.sba.registry.common.model.GenericResponse;
import io.kiki.sba.registry.common.model.Response;
import io.kiki.sba.registry.common.model.elector.Leader;
import io.kiki.sba.registry.server.metadata.MetadataLeaderService;
import io.kiki.sba.registry.server.metadata.resource.filter.LeaderAwareRestController;
import io.kiki.sba.registry.store.api.elector.LeaderElector;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;


@Path("meta/leader")
public class MetaLeaderResource {

    private final static Logger logger = LoggerFactory.getLogger(MetaLeaderResource.class);

    @Autowired
    private MetadataLeaderService metadataLeaderService;

    @Autowired
    private LeaderElector leaderElector;

    @GET
    @Path("query")
    @Produces(MediaType.APPLICATION_JSON)
    @LeaderAwareRestController
    public GenericResponse<Leader> queryLeader() {
        logger.info("[queryLeader] begin");

        try {
            String leader = metadataLeaderService.getLeader();
            long epoch = metadataLeaderService.getLeaderEpoch();
            if (StringUtils.isBlank(leader)) {
                return new GenericResponse<Leader>().fillFailed("leader is null.");
            }

            Leader leaderInfo = new Leader(leader, epoch);
            return new GenericResponse<Leader>().fillSucceed(leaderInfo);
        } catch (Throwable throwable) {
            logger.error("[queryLeader] error.", throwable);
            return new GenericResponse<Leader>().fillFailed(throwable.getMessage());
        }
    }

    @PUT
    @Path("/quit/election")
    @Produces(MediaType.APPLICATION_JSON)
    public Response quitElection() {
        logger.info("[quitElection] begin");

        try {
            leaderElector.change2Observer();
            return GenericResponse.buildSuccessResponse();
        } catch (Throwable throwable) {
            logger.error("[quitElection] error.", throwable);
            return GenericResponse.buildFailedResponse(throwable.getMessage());
        }
    }


    protected MetaLeaderResource setMetaLeaderService(MetadataLeaderService metadataLeaderService) {
        this.metadataLeaderService = metadataLeaderService;
        return this;
    }


    protected MetaLeaderResource setLeaderElector(LeaderElector leaderElector) {
        this.leaderElector = leaderElector;
        return this;
    }
}
